0038. 外观数列【中等】
1. 📝 题目描述
「外观数列」是一个数位字符串序列,由递归公式定义:
countAndSay(1) = "1"countAndSay(n)是countAndSay(n-1)的行程长度编码。
行程长度编码(RLE)是一种字符串压缩方法,其工作原理是通过将连续相同字符(重复两次或更多次)替换为字符重复次数(运行长度)和字符的串联。例如,要压缩字符串 "3322251",我们将 "33" 用 "23" 替换,将 "222" 用 "32" 替换,将 "5" 用 "15" 替换并将 "1" 用 "11" 替换。因此压缩后字符串变为 "23321511"。
给定一个整数 n,返回外观数列的第 n 个元素。
示例 1:
txt
输入:n = 4
输出:"1211"1
2
2
解释:
countAndSay(1) = "1"countAndSay(2) = "1" 的行程长度编码 = "11"countAndSay(3) = "11" 的行程长度编码 = "21"countAndSay(4) = "21" 的行程长度编码 = "1211"
示例 2:
txt
输入:n = 1
输出:"1"1
2
2
解释:这是基本情况。
提示:
1 <= n <= 30
进阶:你能迭代解决该问题吗?
2. 🎯 s.1 - 迭代行程长度编码(RLE)
c
char* countAndSay(int n) {
// 初始化第 1 项
char* cur = (char*)malloc(2);
cur[0] = '1';
cur[1] = '\0';
for (int i = 1; i < n; i++) {
int len = strlen(cur);
// 每轮生成的字符串最长为 2*len
char* next = (char*)malloc(2 * len + 2);
int pos = 0, j = 0;
while (j < len) {
char ch = cur[j];
int cnt = 0;
while (j < len && cur[j] == ch) {
j++;
cnt++;
}
// 写入计数和字符
if (cnt >= 10)
next[pos++] = '0' + cnt / 10;
next[pos++] = '0' + cnt % 10;
next[pos++] = ch;
}
next[pos] = '\0';
free(cur);
cur = next;
}
return cur;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
js
/**
* @param {number} n
* @return {string}
*/
var countAndSay = function (n) {
let cur = '1'
for (let i = 1; i < n; i++) {
let next = ''
let j = 0
while (j < cur.length) {
const ch = cur[j]
let cnt = 0
while (j < cur.length && cur[j] === ch) {
j++
cnt++
}
next += cnt + ch
}
cur = next
}
return cur
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
py
class Solution:
def countAndSay(self, n: int) -> str:
cur = "1"
for _ in range(n - 1):
next_s = []
j = 0
while j < len(cur):
ch = cur[j]
cnt = 0
while j < len(cur) and cur[j] == ch:
j += 1
cnt += 1
next_s.append(str(cnt) + ch)
cur = "".join(next_s)
return cur1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- 时间复杂度:
,其中 是迭代次数, 是当前字符串的平均长度 - 空间复杂度:
,每轮只保留当前层和下一层字符串
算法思路:
- 从
"1"出发,迭代n-1轮,每轮对当前字符串做一次 RLE 压缩 - 每轮扫描当前字符串,统计连续相同字符的数量
cnt,拼接cnt + ch到下一层将說明